/**
 * 事件处理函数中的this指向undefined问题
 *
 *    问题原因：
 *        1. 事件处理函数不是我们主动调用的，而是赋值给了某个事件onClick，后续该事件发生时，React内部直接调用 onClick()
 *        2. 类中的函数默认都开启了严格模式，严格模式中 window 是 undefined
 *
 *    解决方案：
 *        1. 在绑定事件时，做 bind 修改 this 指向
 *        2. 【推荐】在构造函数中，提前 bind 修改 this 指向
 *        3. 在绑定事件时，提供一个箭头函数来作为事件处理函数，然后将原本函数作为普通函数在箭头函数内调用
 *        4. 【推荐】定义该事件处理函数时，使用 public class fields + 箭头函数语法。
 */

import React from "react";

class App extends React.Component {
  constructor(props: any) {
    super(props);

    this.fn2 = this.fn2.bind(this);
  }

  state: Readonly<{ count: number }> = {
    count: 10,
  };

  fn1() {
    this.setState({
      count: 100,
    });

    console.log("fn1", this);
  }

  fn2() {
    this.setState({
      count: 200,
    });
    console.log("fn2", this);
  }

  fn3() {
    this.setState({
      count: 300,
    });
    console.log("fn3", this);
  }

  // public class fields 语法 + 箭头函数
  fn4 = () => {
    this.setState({
      count: 400,
    });
    console.log("fn4", this);
  };

  render() {
    console.log("render", this);

    return (
      <div>
        <h1>事件处理</h1>
        <p>Count: {this.state.count}</p>
        <button onClick={this.fn1.bind(this)}>按钮1</button>
        <button onClick={this.fn2}>按钮2</button>
        <button onClick={() => this.fn3()}>按钮3</button>
        <button onClick={this.fn4}>按钮4</button>
      </div>
    );
  }
}

export default App;

// const obj = {
//   name: "张三",

//   fn1() {
//     "use strict";
//     console.log(this);
//   },
// };

// obj.fn1(); // obj 这个对象

// const onClick = obj.fn1;

// onClick(); // window
